/**
 * 
 */
package edu.rit.cs.web.panels;

import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.Arrays;

import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.FormComponentLabel;
import org.apache.wicket.markup.html.form.IChoiceRenderer;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.spring.injection.annot.SpringBean;

import edu.rit.cs.web.pojos.Business;
import edu.rit.cs.ws.MarketServiceProxy;
import edu.rit.cs.ws.SymbolInfo;
import edu.rit.cs.ws.uddi.UDDIService;

/**
 * Panel containing the dropdowns for selecting the web service and the symbol
 * for the quote inquiry. Uses the wicket ajax classes.
 * 
 * @author Abhishek Shrestha (axs1430)
 * @author Juan Saldana (jjs6109)
 * @author Victor Alvarez (vxa1557)
 */
public class QueryPanel extends Panel {
  private static final long serialVersionUID = 1L;

  @SpringBean
  private MarketServiceProxy marketService;
  @SpringBean
  private UDDIService uddiService;

  /**
   * Contains the information of the quote fetched from the inquiry.
   */
  private SymbolInfo symbol;

  public QueryPanel(final String id) throws Exception {
    super(id);
    setOutputMarkupId(true);
    ;

    /* the components */
    final DropDownChoice<Business> serviceDropDown =
      new DropDownChoice<Business>("service", uddiService.findAllBusinesses());
    serviceDropDown.setModel(new Model<Business>(new Business()));
    serviceDropDown.setChoiceRenderer(new IChoiceRenderer<Business>() {
      private static final long serialVersionUID = 1L;

      @Override
      public Object getDisplayValue(final Business business) {
        return String.format("%s - %s", business.getName(),
                business.getService().getName());
      }

      @Override
      public String getIdValue(final Business business, int index) {
        return business.getKey();
      }
    });

    final DropDownChoice<SymbolInfo> symbolDropDown =
      new DropDownChoice<SymbolInfo>("symbol");
    symbolDropDown.setModel(new PropertyModel<SymbolInfo>(this, "symbol"));
    symbolDropDown.setChoiceRenderer(new IChoiceRenderer<SymbolInfo>() {
      private static final long serialVersionUID = 1L;

      @Override
      public Object getDisplayValue(final SymbolInfo info) {
        return String.format("%s - %s", info.getSymbol(), info.getFullname());
      }

      @Override
      public String getIdValue(final SymbolInfo info, int index) {
        return info.getSymbol();
      }
    });

    /* the "Get Quote" button */
    final AjaxLink<Void> getQuoteBtn = new AjaxLink<Void>("getQuoteBtn") {
      private static final long serialVersionUID = 1L;
      
      @Override
      public void onClick(AjaxRequestTarget target) {
        target.add(QueryPanel.this);
        try {
          double quote = marketService.getQuote(symbol.getSymbol());
          info(String.format("The requested quote for %s is $%.3f",
            symbol.getSymbol(), quote));
          
        } catch (RemoteException e) {
          error("Exception thrown when getting the quote: " + e.getMessage());
        }
      }
    };
    getQuoteBtn.setEnabled(false);

    /* the refresh button */
    final AjaxLink<Void> refreshLnk = new AjaxLink<Void>("refreshLnk") {
      private static final long serialVersionUID = 1L;

      @Override
      public void onClick(AjaxRequestTarget target) {
        target.add(QueryPanel.this);

        try {
          serviceDropDown.setChoices(uddiService.findAllBusinesses());
          serviceDropDown.setDefaultModelObject(new Business());
          symbolDropDown.setChoices(new ArrayList<SymbolInfo>());
          symbolDropDown.setDefaultModelObject(new SymbolInfo());
          getQuoteBtn.setEnabled(false);
        } catch (final Exception e) {
          error ("Exception retrieving services list: " + e.getMessage());
        }
      }
    };

    /* add the form labels */
    add(new FormComponentLabel("serviceLbl", serviceDropDown));
    add(new FormComponentLabel("symbolLbl", symbolDropDown));

    /* add the change listeners to the dropdowns */
    serviceDropDown.add(new AjaxFormComponentUpdatingBehavior("onchange") {
      private static final long serialVersionUID = 1L;
      
      @Override
      protected void onUpdate(final AjaxRequestTarget target) {
        target.add(QueryPanel.this);

        try {
          Business business = uddiService.getBusinessDetail(
            serviceDropDown.getConvertedInput().getKey());
          marketService.setEndpoint(business.getService().getUrl());
        } catch (Exception e) {
          error("Exception thrown when connection to selected WS:"
            + e.getMessage());
        }
        getQuoteBtn.setEnabled(false);

        try {

          SymbolInfo[] symbols = marketService.getSymbols();
          if (symbols != null) {
            symbolDropDown.setChoices(Arrays.asList(symbols));
          }

        } catch (RemoteException e) {
          error("Cannot update the list of symbols: " + e.getMessage());
          symbolDropDown.setChoices(new ArrayList<SymbolInfo>());
        }

      }
    });

    symbolDropDown.add(new AjaxFormComponentUpdatingBehavior("onchange") {
      private static final long serialVersionUID = 1L;

      @Override
      protected void onUpdate(final AjaxRequestTarget target) {
        target.add(QueryPanel.this);
        getQuoteBtn.setEnabled(true);
      }
    });

    /* add the components */
    add(serviceDropDown);
    add(symbolDropDown);
    add(getQuoteBtn);
    add(refreshLnk);
    add(new FeedbackPanel("feedback"));
  }

}
